home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / plnk081.zip / pilot-link.0.8.1 / ccexample.cc < prev    next >
C/C++ Source or Header  |  1997-05-23  |  12KB  |  453 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <iostream.h>
  5. #include "pi-source.h"
  6. #include "pi-file.h"
  7. #include "pi-todo.h"
  8. #include "pi-memo.h"
  9. #include "pi-datebook.h"
  10. #include "pi-address.h"
  11.  
  12. #define bool int
  13. #define false 0
  14. #define true 1
  15.  
  16. static char *days[] = {
  17.      "Sunday", "Monday", "Tuesday", "Wednesday",
  18.      "Thursday", "Friday", "Saturday"
  19. };
  20.  
  21. static char *months[] = {
  22.      "January", "February", "March", "April", "May", "June", "July",
  23.      "August", "September", "October", "November", "December"
  24. };
  25.  
  26. // All app info classes subclass from appInfo_t.  You could pass any of
  27. // them to this function to print out the category names.  Mainly it's here
  28. // to show the inheritance, as this has an appInfo_t as it's arguement, but
  29. // can take any of the default app info classes.
  30. void printCategoryNames(appInfo_t &ai) 
  31. {
  32.      char *ptr;
  33.      
  34.      for (short int i = 0; i < 16; i++) {
  35.       // This is sort of dangerous.  You are getting a pointer back to
  36.       // the real data.  That means if you modify what ptr points to, you
  37.       // are changing the value in the class itself.  Don't do that!
  38.       // I can't find a way to keep this from happening.  Even if I do
  39.       // something anal like return a const char *const all you
  40.       // have to do is cast it to char * and then it's modifiable.
  41.       ptr = ai.category(i);
  42.  
  43.       // The first character will be non-null for an existing category
  44.       if (*ptr)
  45.            cout << "Category " << (i + 1) << " is " << ptr << endl;
  46.      }
  47. }
  48.  
  49. void memos(pi_file *pf) 
  50. {
  51.      void *app_info;
  52.      int app_info_size;
  53.      
  54.      if (pi_file_get_app_info(pf, &app_info, &app_info_size) < 0) {
  55.       cerr << "Unable to get app info" << endl;
  56.       return;
  57.      }
  58.  
  59.      // Create mai as an unpacked structure with the memo app info
  60.      memoAppInfo_t mai(app_info);
  61.  
  62.      // packed is now a pointer to an area of memory thta is MEMO_APP_INFO_SIZE
  63.      // bytes long.  You are responsible for release this memory via delete
  64.      void *packed = mai.pack();
  65.      delete packed;
  66.  
  67.      int nentries;
  68.      pi_file_get_entries(pf, &nentries);
  69.      
  70.      unsigned char *buf, packedBuf[0xffff];
  71.      int size, attrs, cat;
  72.      recordid_t uid;
  73.      
  74.      memo_t memo;
  75.      
  76.      for (int entnum = 0; entnum < nentries; entnum++) {
  77.       if (pi_file_read_record(pf, entnum, (void **) &buf, &size,
  78.                   &attrs, &cat, &uid) < 0) {
  79.            cout << "Error reading record number " << entnum << endl;
  80.            return;
  81.       }
  82.  
  83.       /* Skip deleted records */
  84.       if ((attrs & dlpRecAttrDeleted) || (attrs & dlpRecAttrArchived))
  85.            continue;
  86.  
  87.       memo.unpack(buf);
  88.  
  89.       cout << "Memo number " << (entnum + 1) << endl;
  90.       cout << memo.text() << endl << endl;
  91.  
  92.       // Option 1 for getting a packed memo.  Just give an int to be
  93.       // filled in with the size of the memo.  You must free the space
  94.       // returned via delete
  95.       packed = memo.pack(&size);
  96.       delete packed;
  97.  
  98.       // Option 2 for getting a packed memo.  Give a buffer, and an int
  99.       // telling how big it is.  If the buffer is too small to hold the
  100.       // packed data, NULL is returned.  Otherwise, the buffer is filled
  101.       // in with the packed data, a pointer to it is returned, and the
  102.       // integer passed in is reset to be the size of the packed data
  103.       if (memo.pack(packedBuf, &size) == NULL)
  104.            cerr << "Record number " << (entnum + 1) << " too big for "
  105.             << "the buffer you passed in." << endl;
  106.      }
  107. }
  108.  
  109.      
  110. void todos(pi_file *pf) 
  111. {
  112.      void *app_info;
  113.      int app_info_size;
  114.      
  115.      if (pi_file_get_app_info(pf, &app_info, &app_info_size) < 0) {
  116.       cerr << "Unable to get app info" << endl;
  117.       return;
  118.      }
  119.  
  120.      todoAppInfo_t tai(app_info);
  121.      
  122.      // packed is now a pointer to an area of memory that is TODO_APP_INFO_SIZE
  123.      // bytes long.  You are responsible for release this memory via delete
  124.      void *packed = tai.pack();
  125.      delete packed;
  126.      
  127.      int nentries;
  128.      pi_file_get_entries(pf, &nentries);
  129.      
  130.      unsigned char *buf, packedBuf[0xffff];
  131.      int size, attrs, cat;
  132.      recordid_t uid;
  133.      tm *due;
  134.      todo_t todo;
  135.      
  136.      for (int entnum = 0; entnum < nentries; entnum++) {
  137.       if (pi_file_read_record(pf, entnum, (void **) &buf, &size,
  138.                   &attrs, &cat, &uid) < 0) {
  139.            cout << "Error reading record number " << entnum << endl;
  140.            return;
  141.       }
  142.       
  143.       /* Skip deleted records */
  144.       if ((attrs & dlpRecAttrDeleted) || (attrs & dlpRecAttrArchived))
  145.            continue;
  146.  
  147.       todo.unpack(buf);
  148.       
  149.       cout << "Category: " <<  tai.category(cat) << endl;
  150.       if (todo.description())
  151.            cout << "Description: " << todo.description() << endl;
  152.       cout << "Priority: " << todo.priority() << endl;
  153.       cout << "Completed: " << (todo.complete() ? "Yes" : "No") << endl;
  154.       if ((due = todo.due()))
  155.            cout << "Due: " << asctime(due);
  156.       else
  157.            cout << "Due: No Date" << endl;
  158.       if(todo.note())
  159.            cout << "Note: " << todo.note() << endl;
  160.       cout << endl;
  161.  
  162.       // Just like the memo app, you can pack it like this...
  163.       packed = todo.pack(&size);
  164.       delete packed;
  165.  
  166.       // ... or like this
  167.       size = sizeof(packedBuf);
  168.       if (todo.pack(packedBuf, &size) == NULL)
  169.            cerr << "Record number " << (entnum + 1) << " too big for "
  170.             << "the buffer you passed in." << endl;
  171.      }
  172. }
  173.  
  174. // Only works for up to i == 31.  Beyond that, results are undefined
  175. char *freqToStr(const int i) 
  176. {
  177.      static char buf[7];
  178.  
  179.      if (i == 1)
  180.       buf[0] = '\0';
  181.      else if (i == 3 || i == 23)
  182.       (void) sprintf(buf, "%drd ", i);
  183.      else if ((i > 3 && i < 21) || (i > 23 && i < 31))
  184.       (void) sprintf(buf, "%dth ", i);
  185.      else if (i == 21 || i == 31)
  186.       (void) sprintf(buf, "%dst ", i);
  187.      else if (i == 2 || i == 22)
  188.       (void) sprintf(buf, "%dnd ", i);
  189.  
  190.      return buf;
  191. }
  192.  
  193.      
  194. void prettyPrintRepeat(appointment_t *appt) 
  195. {
  196.      tm *timePtr;
  197.      
  198.      if ((timePtr = appt->repeatEnd()))
  199.       cout << "This event repeats until " << asctime(timePtr);
  200.      else
  201.       cout << "This event repeats forever" << endl;
  202.  
  203.      int freq = appt->repeatFreq();
  204.      int on = appt->repeatOn();
  205.      
  206.      bool found = false;
  207.  
  208.      switch (appt->repeatType()) {
  209.      case appointment_t::daily:
  210.           cout << "It repeats every " << freqToStr(freq) << "day";
  211.           break;
  212.      case appointment_t::weekly:
  213.      {
  214.           cout << "It repeats every " << freqToStr(freq) << "week on ";
  215.  
  216.           for (int i = 0; i < 7; i++) {
  217.            if (on & (1 << i)) {
  218.             if (found)
  219.                  cout << " and ";
  220.             else
  221.                  found = true;
  222.             cout << days[i];
  223.            }
  224.           }
  225.           cout << endl;
  226.           break;
  227.      }
  228.      case appointment_t::monthlyByDay:
  229.           cout << "It repeats on the ";
  230.           
  231.           switch (on / 7) {
  232.           case 0:
  233.                cout << "first ";
  234.                break;
  235.           case 1:
  236.                cout << "second ";
  237.                break;
  238.           case 2:
  239.                cout << "third ";
  240.                break;
  241.           case 3:
  242.                cout << "fourth ";
  243.                break;
  244.           default:
  245.                cout << "last ";
  246.           }
  247.  
  248.           cout << days[on % 7] << " of every month";
  249.           break;
  250.      case appointment_t::monthlyByDate:
  251.           cout << "It repeats every " << freqToStr(freq);
  252.           timePtr = appt->beginTime();
  253.           cout << "month on the " << freqToStr(timePtr->tm_mday) << endl;
  254.           cout << endl;
  255.           break;
  256.      case appointment_t::yearly:
  257.           cout << "It repeats every " << freqToStr(freq) << "year on ";
  258.           timePtr = appt->beginTime();
  259.           cout << months[timePtr->tm_mon] << " " << timePtr->tm_mday;
  260.           cout << endl;
  261.           break;
  262.      default:
  263.           cerr << "Internal error" << endl;
  264.      }
  265. }
  266.  
  267. void datebook(pi_file *pf) 
  268. {
  269.      void *app_info;
  270.      int app_info_size;
  271.      
  272.      if (pi_file_get_app_info(pf, &app_info, &app_info_size) < 0) {
  273.       cerr << "Unable to get app info" << endl;
  274.       return;
  275.      }
  276.      
  277.      appointmentAppInfo_t aai(app_info);
  278.      
  279.      // packed is now a pointer to an area of memory that is
  280.      // APPOINTMENT_APP_INFO_SIZE bytes long.  You are responsible for
  281.      // release this memory via delete
  282.      void *packed = aai.pack();
  283.      delete packed;
  284.      
  285.      int nentries;
  286.      pi_file_get_entries(pf, &nentries);
  287.  
  288.      unsigned char *buf;
  289.      int size, attrs, cat;
  290.      recordid_t uid;
  291.      tm *timePtr;
  292.      appointment_t appt;
  293.      
  294.      for (int entnum = 0; entnum < nentries; entnum++) {
  295.       if (pi_file_read_record(pf, entnum, (void **) &buf, &size,
  296.                   &attrs, &cat, &uid) < 0) {
  297.            cout << "Error reading record number " << entnum << endl;
  298.            return;
  299.       }
  300.       
  301.       /* Skip deleted records */
  302.       if ((attrs & dlpRecAttrDeleted) || (attrs & dlpRecAttrArchived))
  303.            continue;
  304.       
  305.       appt.unpack(buf);
  306.       
  307.       if (appt.untimed() == false) {
  308.            cout << "Begin Time:  " << asctime(appt.beginTime());
  309.            cout << "End Time:    " << asctime(appt.endTime());
  310.       } else
  311.            cout << "Untimed event" << endl;
  312.  
  313.       if (appt.hasAlarm()) {
  314.            cout << "The alarm is set to go off " << appt.advance() << " ";
  315.  
  316.            switch (appt.advanceUnits()) {
  317.            case appointment_t::minutes:
  318.             cout << "minutes";
  319.             break;
  320.            case appointment_t::hours:
  321.             cout << "hours";
  322.             break;
  323.            case appointment_t::days:
  324.             cout << "days";
  325.            default:
  326.             cout << "(internal error)";
  327.            }
  328.  
  329.            cout << " before the event" << endl;
  330.       } else
  331.            cout << "There is not an alarm set for this event" << endl;
  332.  
  333.       if (appt.repeatType() != appointment_t::none)
  334.            prettyPrintRepeat(&appt);
  335.       else
  336.            cout << "Event does not repeat" << endl;
  337.  
  338.       if ((timePtr = appt.exceptions())) {
  339.            size = appt.numExceptions();
  340.            cout << "I seem to have " << size << " exceptions:" << endl;
  341.            for (int i = 0; i < size; i++)
  342.             cout << "\t" << asctime(&timePtr[i]);
  343.       }
  344.  
  345.       cout << "Description: " << appt.description() << endl;
  346.  
  347.       if (appt.note())
  348.            cout << "Note: " << appt.note() << endl;
  349.  
  350.       cout << endl;
  351.      }
  352. }
  353.  
  354.  
  355. void addresses(pi_file *pf) 
  356. {
  357.      
  358.      void *app_info;
  359.      int app_info_size;
  360.      
  361.      if (pi_file_get_app_info(pf, &app_info, &app_info_size) < 0) {
  362.       cerr << "Unable to get app info" << endl;
  363.       return;
  364.      }
  365.  
  366.      addressAppInfo_t aai(app_info);
  367.  
  368.      printCategoryNames(aai);
  369.      
  370.      // packed is now a pointer to an area of memory that is
  371.      // ADDRESS_APP_INFO_SIZE bytes long.  You are responsible for release this
  372.      // memory via delete
  373.      void *packed = aai.pack();
  374.      delete packed;
  375.      
  376.      int nentries;
  377.      pi_file_get_entries(pf, &nentries);
  378.      
  379.      unsigned char *buf, packedBuf[0xffff];
  380.      int size, attrs, cat;
  381.      recordid_t uid;
  382.      address_t address;
  383.      char *phonePtr;
  384.      
  385.      for (int entnum = 0; entnum < nentries; entnum++) {
  386.       if (pi_file_read_record(pf, entnum, (void **) &buf, &size,
  387.                   &attrs, &cat, &uid) < 0) {
  388.            cout << "Error reading record number " << entnum << endl;
  389.            return;
  390.       }
  391.       
  392.       /* Skip deleted records */
  393.       if ((attrs & dlpRecAttrDeleted) || (attrs & dlpRecAttrArchived))
  394.            continue;
  395.  
  396.       address.unpack(buf);
  397.       
  398.       cout << "Category: " <<  aai.category(cat) << endl;
  399.       phonePtr = address.entry(address_t::lastName);
  400.       if (phonePtr)
  401.            cout << "Last Name: " << phonePtr << endl;
  402.       for (cat = address_t::phone1; cat <= address_t::phone5; cat++)
  403.            if ((phonePtr = address.entry((address_t::labelTypes_t) cat)))
  404.             cout << "Phone:  " << phonePtr << endl;
  405.       
  406.       // Just like the memo app, you can pack it like this...
  407.       packed = address.pack(&size);
  408.       delete packed;
  409.       
  410.       // ... or like this
  411.       size = sizeof(packedBuf);
  412.       if (address.pack(packedBuf, &size) == NULL)
  413.            cerr << "Record number " << (entnum + 1) << " too big for "
  414.             << "the buffer you passed in." << endl;
  415.      }
  416. }
  417.  
  418. int main(int argc, char **argv) 
  419. {
  420.      if (argc != 2) {
  421.       cerr << "Usage: " << *argv << " [.pdb file]" << endl;
  422.       return 1;
  423.      }
  424.      
  425.      pi_file *pf;
  426.      if ((pf = pi_file_open(*(argv + 1))) == NULL) {
  427.       perror("pi_file_open");
  428.       return 1;
  429.      }
  430.  
  431.      char *slash = strrchr(*(argv + 1), '/');
  432.      if (slash)
  433.     slash++;
  434.      else
  435.     slash = *(argv + 1);
  436.  
  437.      if (!strcmp(slash, "ToDoDB.pdb"))
  438.     todos(pf);
  439.      else if (!strcmp(slash, "DatebookDB.pdb"))
  440.         datebook(pf);
  441.      else if (!strcmp(slash, "AddressDB.pdb"))
  442.     addresses(pf);
  443.      else if (!strcmp(slash, "MemoDB.pdb"))
  444.     memos(pf);
  445.      else 
  446.     cerr << "Unknown database: " << slash << endl;
  447.  
  448.      pi_file_close(pf);
  449.  
  450.      return 0;
  451. }
  452.  
  453.